<template>
  <el-form
    ref="formRef"
    label-width="90px"
    :model="formData"
    label-position="top"
    :rules="state.formRules"
  >
    <el-row :gutter="10">
      <el-col :span="12">
        <el-form-item label="表单名称:" prop="formName">
          <el-input v-model="formData.formName" :maxlength="32" show-word-limit type="text" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="所属分类:" prop="formTypeName">
          <el-cascader
            v-model="formData.formTypeId"
            clearable
            :collapse-tags="true"
            :options="instance.dataList"
            :placeholder="formData.formTypeName || '请选择所属分类'"
            :props="instance.props"
            :show-all-levels="false"
            style="width: 100%"
            @change="handleFormTypeChange"
          />
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="状态:" prop="formStatus">
          <DictSelect
            ref="statusRef"
            v-model:default-value="formData.formStatus"
            dict-code="1002"
            show-all="N"
            expanding
            @change="handleStatusChange"
          />
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="数据存储:" prop="storageType">
          <el-radio-group v-model="formData.storageType">
            <el-radio label="默认表" value="0" />
            <el-radio label="指定表" value="1" />
          </el-radio-group>
        </el-form-item>
      </el-col>
      <el-col :span="8" v-if="formData.storageType === '1'">
        <el-form-item label="主实体:" prop="tableId">
          <div style="display: flex; justify-content: space-between">
            <el-input v-model="formData.tableName" placeholder="请选择数据库表" readonly>
              <template #append>
                <el-button icon="Search" @click="handleOpenDefTablePicker('main')" />
              </template>
            </el-input>
            <el-button
              icon="Delete"
              type="danger"
              @click="handleClearBusTable"
              style="margin-left: 10px"
            ></el-button>
          </div>
        </el-form-item>
      </el-col>
      <el-col :span="24">
        <el-form-item label="表单备注:" prop="formRemark">
          <el-input
            v-model="formData.formRemark"
            :maxlength="256"
            :rows="1"
            show-word-limit
            type="textarea"
          />
        </el-form-item>
      </el-col>
      <el-col :span="24" v-if="formData.storageType === '1'">
        <el-form-item label="关联表:" prop="refList">
          <el-row type="flex" justify="space-between" style="width: 100%" class="header-row">
            <el-col :span="6" style="text-align: center">表名</el-col>
            <el-col :span="6" style="text-align: center">子表外键</el-col>
            <el-col :span="6" style="text-align: center">主表主键</el-col>
            <el-col :span="4" style="text-align: center">关联关系</el-col>
            <el-col :span="2" style="text-align: center"
              ><el-button type="primary" icon="circle-plus" round @click="handleAddRefTable" />
            </el-col>
          </el-row>
          <el-row
            type="flex"
            justify="space-between"
            :gutter="10"
            style="width: 100%; padding: 10px 0px"
            v-for="(row, index) in formData.refList"
            :key="index"
          >
            <el-col :span="6">
              <el-input
                v-model="row.tableName"
                :disabled="!state.subTableEdit"
                placeholder="请选择实体"
                readonly
                style="margin-right: 60px"
              >
                <template #append>
                  <el-button
                    icon="search"
                    :disabled="!state.subTableEdit"
                    @click="handleOpenDefTablePicker('sub', index)"
                  >
                  </el-button>
                </template>
              </el-input>
            </el-col>
            <el-col :span="6">
              <el-select
                v-model="row.subTableColumn"
                :disabled="!state.subTableEdit"
                placeholder="请选择子表外键字段"
                @focus="handleEditSubTable(row, index)"
                @change="val => handleSelectChange(val, index, 'subTableColumn')"
              >
                <el-option
                  v-for="item in state.subTableColumnOptions"
                  :key="item.id"
                  :label="item.columnName"
                  :value="item.columnName"
                />
              </el-select>
            </el-col>
            <el-col :span="6">
              <el-select
                v-model="row.mainTableColumn"
                :disabled="!state.subTableEdit"
                placeholder="请选择与主表的关联字段"
                @change="val => handleSelectChange(val, index, 'mainTableColumn')"
              >
                <el-option
                  v-for="item in state.mainTableColumnOptions"
                  :key="item.id"
                  :label="item.columnName"
                  :value="item.columnName"
                />
              </el-select>
            </el-col>
            <el-col :span="4">
              <el-select
                v-model="row.mainSubRadio"
                :disabled="!state.subTableEdit"
                placeholder="请选择主表与子表的关联关系"
                @change="val => handleSelectChange(val, index, 'mainSubRadio')"
              >
                <el-option
                  v-for="item in state.mainSubRadioOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-col>
            <el-col :span="2" style="text-align: center">
              <el-button
                type="warning"
                icon="remove"
                round
                @click="handleDeleteSubTable(row, index)"
              >
              </el-button>
            </el-col>
          </el-row>
        </el-form-item>
      </el-col>
    </el-row>
    <DefTablePicker
      ref="defTablePickerRef"
      :ingore="getMainTableIdArray"
      :multiple="false"
      @change="handleDefTablePicker"
    />
  </el-form>
</template>

<script setup name="FormDefEdit" lang="ts">
import { filterTreeNode } from "@/utils/common";
import { querySystemTreeNode } from "@/api/admin/system/systemtree/";
import { queryBusColumnList } from "@/api/def/column/";
import DictSelect from "@/components/dictSelect.vue";
import DefTablePicker from "@/components/def/defTablePicker.vue";
import type { FormModel } from "./FormComponentMixin";
import { BasicCascaderProps, useCascader } from "@/hooks/cascader";

const formData = defineModel<FormModel>("formData");
const formRef = ref(null);
const defTablePickerRef = ref(null);

const validRefList = (rule: any, value: any, callback: any) => {
  if (value) {
    if (value.some(n => !n.tableId || !n.mainTableColumn || !n.subTableColumn)) {
      return callback(new Error("关联实体配置未完成"));
    }
    return callback();
  } else {
    return callback();
  }
};

const state = reactive({
  mainTableColumnOptions: [],
  subTableColumnOptions: [],
  mainSubRadioOptions: [
    { label: "1:1", value: "0" },
    { label: "1:N", value: "1" }
  ],
  formRules: {
    formName: [{ required: true, message: "表单名称不能为空", trigger: "blur" }],
    formTypeName: [{ required: true, message: "请选择所属分类", trigger: "blur" }],
    formStatus: [{ required: true, message: "请选择表单状态", trigger: "blur" }],
    refList: [
      {
        validator: validRefList,
        trigger: "blur"
      }
    ]
  },
  openBusTablePickerCommand: "",
  openBusTablePickerIndex: 0,
  subTableEdit: false
});

const initFormType = async () => {
  if (formData.value.formTypeCode) {
    const item = filterTreeNode(cascaderOptions.dataList, formData.value.formTypeCode, "nodeCode");
    if (item) {
      formData.value.formTypeId = item.id;
      formData.value.formTypeCode = item.nodeCode;
      formData.value.formTypeName = item.text;
    }
  }
};

const cascaderOptions = reactive<BasicCascaderProps>({
  autoLoad: false,
  queryForm: { treeCode: "form" },
  props: {
    checkStrictly: true,
    multiple: false,
    emitPath: false,
    label: "text",
    value: "id",
    leaf: "leaf",
    lazy: true
  },
  onLoaded: initFormType,
  queryFunction: querySystemTreeNode
});

const { instance: instance, queryCascaderData } = useCascader(cascaderOptions);

const getMainTableIdArray = computed(() => {
  const ids = [];
  if (formData.value && formData.value.tableId) {
    ids.push(formData.value.tableId);
  }
  if (formData.value && formData.value.refList) {
    formData.value.refList.forEach(item => {
      ids.push(item.tableId);
    });
  }
  return ids;
});

const queryBusColumnTableData = async (tableId, command) => {
  queryBusColumnList({ tableId: tableId }).then(res => {
    if (res && res.code === 200) {
      if (command === "main") {
        state.mainTableColumnOptions = [];
        state.mainTableColumnOptions = res.data;
      } else {
        state.subTableColumnOptions = [];
        state.subTableColumnOptions = res.data;
      }
    }
  });
};

const handleStatusChange = val => {
  formData.value.formStatus = val;
};

const handleSelectChange = (val, index, columnName) => {
  formData.value.refList[index][columnName] = val;
};

const handleDeleteSubTable = (row, index) => {
  formData.value.refList.splice(index, 1);
};

const handleEditSubTable = row => {
  state.subTableEdit = true;
  if (row.tableId) {
    queryBusColumnTableData(row.tableId, "sub");
  } else {
    state.subTableColumnOptions = [];
  }
};

const handleAddRefTable = () => {
  const newRow = {
    id: "",
    tableId: "",
    tableName: "",
    formName: "",
    mainTableColumn: "id",
    subTableColumn: "",
    mainSubRadio: "0"
  };
  state.subTableColumnOptions = [];
  state.subTableEdit = true;
  if (!formData.value.refList) {
    formData.value.refList = [];
  }
  formData.value.refList.push(newRow);
};

const handleClearBusTable = () => {
  formData.value.tableId = "";
  formData.value.tableName = "";
};

const handleOpenDefTablePicker = (openBusTablePickerCommand, index?: number) => {
  if (openBusTablePickerCommand === "sub") {
    state.openBusTablePickerIndex = index;
  }
  state.openBusTablePickerCommand = openBusTablePickerCommand;
  defTablePickerRef.value.show();
};

const handleDefTablePicker = rows => {
  if (state.openBusTablePickerCommand === "main") {
    formData.value.tableId = rows.id;
    formData.value.tableName = rows.tableName;
    queryBusColumnTableData(rows.id, "main");
  } else {
    formData.value.refList[state.openBusTablePickerIndex]["tableId"] = rows.id;
    formData.value.refList[state.openBusTablePickerIndex]["tableName"] = rows.tableName;
    queryBusColumnTableData(rows.id, "sub");
  }
};

const handleFormTypeChange = () => {
  const item = filterTreeNode(cascaderOptions.dataList, formData.value.formTypeId, "id");
  if (item) {
    formData.value.formTypeId = item.id;
    formData.value.formTypeCode = item.nodeCode;
    formData.value.formTypeName = item.text;
  }
};

watchEffect(() => {
  if (formData.value && formData.value.tableId) {
    queryBusColumnTableData(formData.value.tableId, "main");
  }
  if (formData.value && formData.value.formTypeCode) {
    initFormType();
  }
  if (formData.value && formData.value.id) {
    state.subTableEdit = true;
  }
});

onMounted(() => {
  queryCascaderData();
});

const validate = () => {
  return new Promise<void>((resolve, reject) => {
    formRef.value
      .validate()
      .then(valid => {
        resolve(valid);
      })
      .catch(err => {
        reject(Object.keys(err).map(v => err[v][0].message));
      });
  });
};

defineExpose({
  validate
});
</script>

<style lang="scss" scoped>
.designer-base-scrollbar {
  overflow-x: hidden;
  min-height: calc(100vh - 160px);
  padding: 0px 10px;
}
.header-row {
  background-color: $main-bgc;
}
</style>
